package cn.maihe.elg.operation.supports.invoice.nuonuo;

import cn.maihe.elg.operation.config.UploadConfig;
import cn.maihe.elg.operation.model.enums.AttachmentFileType;
import cn.maihe.elg.operation.model.enums.InvoiceReversalFlag;
import cn.maihe.elg.operation.model.enums.InvoiceStatusEnum;
import cn.maihe.elg.operation.repository.entity.*;
import cn.maihe.elg.operation.service.guarantee.GuaranteeService;
import cn.maihe.elg.operation.service.invoice.InvoiceInfoService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.service.order.GuaranteeAttachmentInfoService;
import cn.maihe.elg.operation.supports.system.ElgResourceService;
import cn.maihe.elg.operation.utils.ElgLogger;
import cn.maihe.framework.starter.mybatis.mapper.PlusEntityWrapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @Description
 * @Author caixh
 * @Date 2021/5/13.
 */
@Component
@Slf4j
public class InvoiceDownLoadHelper {
    @Resource
    private InvoiceInfoService invoiceInfoService;
    @Resource
    private UploadConfig uploadConfig;
    @Resource
    private GuaranteeService guaranteeService;
    @Resource
    private AcceptOrderInfoService acceptOrderInfoService;
    @Value("${resourcesDir}")
    private String resourcesDir;
    @Resource
    private GuaranteeAttachmentInfoService guaranteeAttachmentInfoService;
    @Resource
    private ElgResourceService elgResourceService;


    /**
     * 下载电子发票，保存路径为原先存储路径不变
     */
    public Path downloadInvoice(String invoicePdfUrl) {
        Assert.hasText(invoicePdfUrl, "发票下载地址不能为空");
        URLConnection conn = null;
        try {
            URL url = new URL(invoicePdfUrl);
            conn = url.openConnection();
        } catch (IOException e) {
            throw new RuntimeException("发票下载地址连接失败：" + e.getMessage(), e);
        }
        UploadConfig.Upload upload = uploadConfig.getUpload().get("invoice");
        if (upload == null) {
            ElgLogger.error(log, l -> l.error("发票下载保存路径未配置"));
            throw new RuntimeException("发票下载保存路径未配置");
        }
        // 生成一个随机的名称，避免文件名重复
        UUID uuid = UUID.randomUUID();
        // 保存文件
        File saveFile = new File(upload.getPath() + uuid + ".pdf");

        try (InputStream inputStream = conn.getInputStream();
             FileOutputStream out = new FileOutputStream(saveFile)) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
        } catch (IOException e) {
            ElgLogger.error(log, log -> log.error("下载保存电子发票pdf异常：{}", e.getMessage(), e));
            throw new RuntimeException("下载保存电子发票异常：" + e.getMessage());
        }
        if (!saveFile.exists() || saveFile.length() == 0) {
            throw new RuntimeException("电子发票pdf不存在或文件大小为0");
        }
        return saveFile.toPath();
    }

    @Transactional(rollbackFor = Exception.class)
    public void savePdfAndUpdateInvoice(Path invoicePdf,InvoiceInfoDO invoiceInfoDO){
        AcceptOrderInfoVo vo = new AcceptOrderInfoVo();
        vo.setInvoiceId(invoiceInfoDO.getId());
        //合并开票情况下，发票id对应多个受理订单号
        List<AcceptOrderInfoDO> acceptOrderInfoDOS = acceptOrderInfoService.selectOrderByInvoice(vo);
        Integer invoiceType = invoiceInfoDO.getInvoiceType();
        AttachmentFileType attachmentFileType =AttachmentFileType.TYPE_8;
        String appendFileName = "蓝票";
        boolean isReversal = (invoiceType!=null && invoiceType==2)?true:false;
        if(isReversal){
            //冲红发票
            attachmentFileType =AttachmentFileType.TYPE_16;
            appendFileName = "红票";
            AcceptOrderInfoDO acceptOrderInfo = acceptOrderInfoService.getByAcceptOrderNo(invoiceInfoDO.getAcceptOrderNos());
            acceptOrderInfoDOS = Lists.newArrayList(acceptOrderInfo);
        }
        for (AcceptOrderInfoDO curApplyOrder : acceptOrderInfoDOS) {
            //每个订单独自保存一份
            String filePath = elgResourceService.transferAndSaveFile(invoicePdf, "ofd", curApplyOrder.getAcceptOrderNo(), curApplyOrder.getAcceptOrderNo() + appendFileName);
            Path invoicePdfPath = elgResourceService.getFileByRelativePath(filePath).toPath();

            GuaranteeAttachmentInfoDO invoiceAttachmentInfo = new GuaranteeAttachmentInfoDO();
            invoiceAttachmentInfo.setAcceptOrderNo(curApplyOrder.getAcceptOrderNo());
            invoiceAttachmentInfo.setCenterId(curApplyOrder.getCenterId());
            invoiceAttachmentInfo.setOrgId(curApplyOrder.getOrgId());
            invoiceAttachmentInfo.setType(attachmentFileType.getType());
            invoiceAttachmentInfo.setFilePath(filePath);
            invoiceAttachmentInfo.setFileType(elgResourceService.getFileType(invoicePdfPath));
            invoiceAttachmentInfo.setFileName(elgResourceService.getFileName(invoicePdfPath));
            invoiceAttachmentInfo.setFileMd5(elgResourceService.getFileMD5AsHex(invoicePdfPath));
            guaranteeAttachmentInfoService.saveOrUpdateAttachmentInfo(invoiceAttachmentInfo);
        }


        invoiceInfoDO.setInvoiceImg(elgResourceService.getRelativePath(invoicePdf));
        invoiceInfoDO.setStatus(InvoiceStatusEnum.INVOICED.getValue());
        invoiceInfoDO.setRemark(appendFileName+"开票&下载完成");
        invoiceInfoService.updateById(invoiceInfoDO);
        if(isReversal){
            InvoiceInfoDO updateOrigInvoiceInfo = InvoiceInfoDO.builder().invoiceReversalFlag(InvoiceReversalFlag.SUCCESS.getFlag()).build();
            PlusEntityWrapper<InvoiceInfoDO> wrapper = InvoiceInfoDOCondition.builder().andInvoiceReversalIdEq(invoiceInfoDO.getId()).build();
            invoiceInfoService.update(updateOrigInvoiceInfo, wrapper);

            // 临时冲红发票记录 invoice_type = 3
            InvoiceInfoDO invoiceInfoTemp = invoiceInfoService.selectOne(wrapper);
            if(Objects.nonNull(invoiceInfoTemp)){
                // 更新蓝票的冲红状态
                Integer update = invoiceInfoService.update(updateOrigInvoiceInfo, InvoiceInfoDOCondition.builder().andInvoiceReversalIdEq(invoiceInfoTemp.getId()).build());
                ElgLogger.info(log, log -> log.info("临时冲红发票记录 invoice_type{};蓝票冲红状态 update.size{}",invoiceInfoTemp.getInvoiceType(),update));
            }else {
                ElgLogger.warn(log, log -> log.info("临时冲红发票记录 invoiceInfoTemp is null"));
            }
        }

    }

}
